package com.eternal.widget.guqiang;

import android.content.Context;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.eternal.framework.utils.ConvertUtils;
import com.eternal.widget.R;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * Created by Administrator
 * On 2020/5/22
 * Description:
 * @author Administrator
 */
public class FanProgressBar extends ConstraintLayout  {
    private Listener listener;
    private TextView title, minTitle, maxTitle, show;
    private ImageView circle;
    private View progress, progressBack;
    private int width, cWidth;
    private int min, distance, interval, now;
    private float px;
    private float dWidth;
    private Disposable addSubs,minusSubs;

    public FanProgressBar(Context context) {
        this(context, null);
    }

    public FanProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FanProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        View view = View.inflate(context, R.layout.layout_fan_progress_bar, this);
        title=view.findViewById(R.id.txt_title);
        minTitle =view.findViewById(R.id.txt_min);
        maxTitle =view.findViewById(R.id.txt_max);
        show=view.findViewById(R.id.txt_show);
        circle=view.findViewById(R.id.img_circle);
        progress=view.findViewById(R.id.v_progress);
        progressBack = view.findViewById(R.id.v_progress_background);

        addSubs= Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(final ObservableEmitter<Object> emitter) throws Exception {
                findViewById(R.id.img_add).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        float x=(now+1-min+interval)*dWidth+cWidth/2f;
                        moveView(x);
                        if(listener!=null){
                            listener.onDown(false);
                            listener.onChange(now);
                        }
                        emitter.onNext(v);
                    }
                });
            }
        }).debounce(500, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) {
                if(listener!=null){
                    listener.onUp(false,now);
                }
            }
        });
        minusSubs= Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(final ObservableEmitter<Object> emitter) throws Exception {
                findViewById(R.id.img_minus).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        emitter.onNext(this);
                        float x=(now-1-min-interval)*dWidth+cWidth/2f;
                        moveView(x);
                        if(listener!=null){
                            listener.onDown(false);
                            listener.onChange(now);
                        }
                    }
                });
            }
        }).debounce(1, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) {
                if(listener!=null){
                    listener.onUp(false, now);
                }
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                if (!inRangeOfView(event)) {
                    return false;
                }
                if(null!=listener){
                    listener.onDown(true);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                moveView(x);
                if(null!=listener){
                    listener.onChange(now);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (null != listener) {
                    listener.onUp(true, now);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
            default:
                return super.onTouchEvent(event);
        }
        return true;
    }

    public void setStyle(String title, String minStr, String maxStr, int min, int distance){
        setTitle(title);
        this.minTitle.setText(minStr);
        this.maxTitle.setText(maxStr);
        this.min=min;
        this.distance=distance;
    }

    public void setTitle(String title){
        this.title.setText(title);
    }

    public void setListener(Listener listener){
        this.listener=listener;
    }

    public void moveView(float x){
        int max = width - cWidth;
        x-=cWidth/2f;
        x = (x < 0 ? 0 : (x > max ? max : x));
        //当前移动的长度换算成显示文字
        now= Math.round(x/dWidth+min);
        show.setText(String.valueOf(now));
        int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        show.measure(spec, spec);
        circle.setTranslationX(getTx());
        int tvShowTextWidth = show.getMeasuredWidth();
        float mCurrentIvBarX = circle.getX();
        if(mCurrentIvBarX==0){
            show.setTranslationX(0);
        }else if(mCurrentIvBarX==max){
            show.setTranslationX(width-tvShowTextWidth);
        }else{
            float tvshowTextX = mCurrentIvBarX + cWidth / 2f - tvShowTextWidth / 2f;
            show.setTranslationX(tvshowTextX < 0 ? 0 : tvshowTextX + tvShowTextWidth > width ? width - tvShowTextWidth : tvshowTextX);
        }
        moveProgress(circle.getTranslationX());
    }

    private void moveProgress(float x) {
        if (Math.round(px / dWidth + min) == now) {
            progress.setTranslationX(circle.getTranslationX());
            ViewGroup.LayoutParams params = progress.getLayoutParams();
            params.width = 1;
            progress.setLayoutParams(params);
            return;
        }
//        if (x > px) {
//            x = width - x;
//        } else {
//            x = px - x + cWidth;
//        }
//        x = (int) x;
//        if (x == 0) {
//            x = width - circle.getTranslationX();
//        }
//        progress.setTranslationX(circle.getTranslationX());
//        ViewGroup.LayoutParams params = progress.getLayoutParams();
//        params.width = (int) x;
//        progress.setLayoutParams(params);

            if (x > px) {
                x = x - px;
                progress.setTranslationX(px);
            } else {
                progress.setTranslationX(0);
            }
            x = (int) x;
            if (x == 0) {
                x = 1;
            }
            ViewGroup.LayoutParams params = progress.getLayoutParams();
            params.width = (int) x;
            progress.setLayoutParams(params);

    }

    public float getTx(){
        return (now-min)*dWidth;
    }

    public void setProgress(int num){
        moveView((num-min)*dWidth+cWidth/2f);
        now=num;
        if(listener!=null){
            listener.onChange(now);
        }
    }

    /**
     * 是否按到了view上
     *
     * @param ev
     * @return
     */
    private boolean inRangeOfView(MotionEvent ev) {
        int[] location = new int[2];
        circle.getLocationOnScreen(location);
        float ivBarX = circle.getX();
        float ivBarY = circle.getY();
        float right = ivBarX + circle.getMeasuredWidth();
        float top = 0;
        float bottom = ivBarY + circle.getMeasuredHeight();
        return ev.getY() >= top && ev.getY() <= bottom && ev.getX() >= ivBarX - ConvertUtils.dp2px(30)
                && ev.getX() <= right + ConvertUtils.dp2px(30);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width= progressBack.getMeasuredWidth();
        cWidth=circle.getMeasuredWidth();
        dWidth=(width-cWidth)/ ((float) distance);
        post(new Runnable() {
            @Override
            public void run() {
                moveView((now-min)*dWidth+cWidth/2f);
            }
        });

    }

    public interface Listener{
        void onDown(boolean isProgress);
        void onUp(boolean isProgress, int value);
        void onChange(int value);
    }
}
